<?php

namespace app\admin\controller;

use app\common\controller\Backend;
use app\admin\model\Deal;
use app\common\model\Order;
use app\common\model\User;
use think\Db;
use think\Log;

/**
 * 挂单管理
 *
 * @icon fa fa-circle-o
 */
class DealMatch extends Backend
{
    
    /**
     * Deal模型对象
     * @var \app\admin\model\Deal
     */
    protected $model = null;
    protected $searchFields = 'id,deal_sn,user_id,cny';
    protected $noNeedRight = '*';

    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('Deal');
        $this->view->assign("typeList", $this->model->getTypeList());
        $this->view->assign("statusList", $this->model->getStatusList());
        $this->view->assign("payStatusList", $this->model->getPayStatusList());
    }

    public function index($ids = '')
    {
        $this->request->filter(['strip_tags']);
        $row = $this->model->get($ids);     //  获取当前选择的一笔交易
        if (!$row)
        {
            $this->error(__('No Results were found'));
        }


        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            return $this->match_list($row); //  返回要匹配的列表
        }
        $this->assign('row',$row);
        $this->assign('ids',$ids);
        return $this->view->fetch();
    }

    //  匹配列表
    private function match_list($row)
    {
        //  加载api配置文件
        \think\Config::load(APP_PATH . 'api/config.php');
        $type_id = $row->type == config('DealType.Buy') ? config('DealType.Sold') : config('DealType.Buy');
        $my_where = [
            //'residue_cny' => ['<=', $row->residue_cny],     //  查询剩余未交易量
            'residue_cny' => ['>', 0],     //  查询剩余未交易量
            'user_id' => ['<>', $row->user_id], //  不是自己的交易数据
            'type' => $type_id,    //  两级反转
            //'status'    =>  config('DealStatus.NoDeal')
        ];

        list($where, $sort, $order, $offset, $limit) = $this->buildparams();    //  构建查询语句

        $total = $this->model
            ->where($my_where)
            ->where($where)
            ->order($sort, $order)
            ->count();    //  可匹配的列表
        $deal_list = $this->model
            //->with('user')
            ->where($my_where)
            ->where($where)
            ->order($sort, $order)
            ->limit($offset, $limit)
            ->select();    //  可匹配的列表

        $deal_list = collection($deal_list)->toArray();
        //  添加用户信息
        foreach ($deal_list as $k=>$v)
        {
            $user_info = Db::name('user')
                ->alias('u')
                ->join('user_certification c','c.user_id = u.id','left')
                ->where(['u.id'=>$v['user_id']])
                ->find();
            if ($user_info)
            {
                $deal_list[$k]['user'] = $user_info;
            }

            $line_info = \db('user')
                ->alias('u')
                ->field('u.id,u.mobile,c.bank_realname')
                ->join('user_certification c','c.user_id = u.id','left')
                ->join('user_recommend r','r.line_id = u.id','left')
                ->where('r.user_id','=',$v['user_id'])
                ->find();
            $deal_list[$k]['line'] = $line_info;
        }
        $result = array("total" => $total, "rows" => $deal_list);
        return json($result);
    }

    /**
     * 交易匹配确认
     * @param string $ids 勾选记录id
     * @param string $main_id   主交易id
     * @throws \think\exception\DbException
     */
    public function deal_confirm($ids = '',$main_id = '')
    {
        \think\Config::load(APP_PATH . 'api/config.php');
        if (!$main_id || !$ids)
        {
            $this->error('参数不正确');
        }

        //  查找需要处理的主订单
        $main_deal = Deal::get($main_id);
        if (!$main_deal)
        {
            $this->error('交易记录不存在');
        }

        if ($main_deal->status != config('DealStatus.NoDeal') && $main_deal->residue_cny <=0)
        {
            $this->error('交易已匹配过或已取消');
        }

        //  查询被勾选的记录
        $ids = explode(',',$ids);
        $deal_list = [];$price = 0;
        foreach ($ids as $did)
        {
            $tmp_deal = Deal::get($did);
            if (!$tmp_deal)
            {
                $this->error('勾选交易不存在：'.$did);
            }
            /*if ($tmp_deal->status != config('DealStatus.NoDeal'))
            {
                $this->error('匹配失败！交易ID '.$did.' 状态异常：'.$tmp_deal->status_text);
            }*/

            $deal_list[] = $tmp_deal;
            $price += $tmp_deal->cny;
        }
        //  查看能否匹配
        /*if ($price != $main_deal->cny)
        {
            $this->error('价格不相同，匹配失败');
        }*/

        //  正式匹配
        if ($main_deal->type == config('DealType.Buy'))
        {
            //  主为买入
            $result = $this->match_buy_data($deal_list,$main_deal);
        }else
        {
            $result = $this->match_sold_data($deal_list,$main_deal);
        }

        if ($result === true)
        {
            $this->success('匹配交易成功');
        }else
        {
            $this->error('匹配交易失败');
        }

    }

    //  买入挂单
    private function match_buy_data($deal_list,$main_deal)
    {
        $time = time();
        $main_deal_residue_cny = $main_deal->residue_cny;   //  剩余应该交易的cny
        \think\Config::load(APP_PATH.'api/config.php');

        //  生成要保存的数据
        $order_data = [];

        //  主记录为买入
        foreach ($deal_list as $k => $item)
        {
            if ($main_deal_residue_cny <= 0)
            {
                unset($deal_list[$k]);
                continue;
            }

            if ($item->residue_cny > $main_deal_residue_cny)
            {   //主挂单快结束了
                $deal_cny = $main_deal_residue_cny;
                $deal_list[$k]->residue_cny -= $deal_cny;    //  减少剩余量
                $main_deal_residue_cny = 0; //  重置放到最后
            }
            else
            {
                $deal_cny = $item->residue_cny;
                $deal_list[$k]->residue_cny = 0;    //  清空剩余量
                $main_deal_residue_cny = $main_deal_residue_cny - $deal_cny;
            }

            //  所有记录
            $deal_list[$k]->status = config('DealStatus.Dealing');
            $deal_list[$k]->match_time = $time;
            //  主订单的剩余量更新
            $main_deal->residue_cny -= $deal_cny;

            //  要插入的数据
            $order_data[] = [
                'order_sn'  =>  generate_order_id($item->user_id),
                'buy_deal_sn'   =>  $main_deal->deal_sn,
                'buy_user_id'   =>  $main_deal->user_id,
                'sale_deal_sn'  =>  $item->deal_sn,
                'sale_user_id'  =>  $item->user_id,
                'create_time'   =>  $time,
                'pay_time'      =>  0,
                'complete_time' =>  0,
                'type'          =>  config('DealType.Buy'),
                'status'        =>  config('OrderStatus.NoDeal'),
                'cny'           =>  $deal_cny
            ];

        }

        //  事务保存
        $order = new Order();
        Db::startTrans();
        try{
            //  更新所有被勾选交易的状态
            foreach ($deal_list as $item)
            {
                /*$item->status = config('DealStatus.Dealing');
                $item->match_time = $time;*/
                $sold_user_info = User::get($item->user_id);
                send_matched_sms($sold_user_info->mobile,$item->deal_sn);   //  发送短信提醒
                $item->save();
            }
            //  批量生成 一对一 订单号
            $order->isUpdate(false)->allowField(true)->saveAll($order_data);
            //  更新主记录的状态
            $main_deal->status = config('DealStatus.Dealing');
            $main_deal->match_time = $time;
            $buy_user_info = User::get($main_deal->user_id);
            send_matched_sms($buy_user_info->mobile,$main_deal->deal_sn);   //  发送短信提醒
            $main_deal->save();
            Db::commit();
            return true;
        }catch (\Exception $e) {
            Db::rollback();
            Log::error('匹配交易失败：'.json_encode($e->getMessage()));
            return $e->getMessage();
        }
    }

    //  卖出匹配挂单
    private function match_sold_data($deal_list,$main_deal)
    {
        $time = time();
        $main_deal_residue_cny = $main_deal->residue_cny;   //  剩余应该交易的cny
        \think\Config::load(APP_PATH.'api/config.php');

        //  生成要保存的数据
        $order_data = [];

        //  主记录为卖出
        foreach ($deal_list as $k => $item)
        {
            if ($main_deal_residue_cny <= 0)
            {
                unset($deal_list[$k]);
                continue;
            }

            if ($item->residue_cny > $main_deal_residue_cny)
            {   //主挂单快结束了
                $deal_cny = $main_deal_residue_cny;
                $main_deal_residue_cny = 0;
                $deal_list[$k]->residue_cny -= $deal_cny;    //  减少剩余量
            }
            else
            {
                $deal_cny = $item->residue_cny;
                $main_deal_residue_cny = $main_deal_residue_cny - $deal_cny;
                $deal_list[$k]->residue_cny = 0;    //  清空剩余量
            }

            //  所有记录
            $deal_list[$k]->status = config('DealStatus.Dealing');
            $deal_list[$k]->match_time = $time;
            //  主订单的剩余量更新
            $main_deal->residue_cny -= $deal_cny;

            //  要插入的数据
            $order_data[] = [
                'order_sn'      =>  generate_order_id($item->user_id),
                'buy_deal_sn'   =>  $item->deal_sn,
                'buy_user_id'   =>  $item->user_id,
                'sale_deal_sn'  =>  $main_deal->deal_sn,
                'sale_user_id'  =>  $main_deal->user_id,
                'create_time'   =>  $time,
                'pay_time'      =>  0,
                'complete_time' =>  0,
                'type'          =>  config('DealType.Sold'),    //  卖出为主
                'status'        =>  config('OrderStatus.NoDeal'),
                'cny'           =>  $deal_cny
            ];

        }

        //  事务保存
        $order = new Order();
        Db::startTrans();
        try{
            //  更新所有被勾选交易的状态
            foreach ($deal_list as $item)
            {
                /*$item->status = config('DealStatus.Dealing');
                $item->match_time = $time;*/
                $buy_user_info = User::get($item->user_id);
                send_matched_sms($buy_user_info->mobile,$item->deal_sn);   //  发送短信提醒
                $item->save();
            }
            //  批量生成 一对一 订单号
            $order->isUpdate(false)->allowField(true)->saveAll($order_data);
            //  更新主记录的状态
            $main_deal->status = config('DealStatus.Dealing');
            $main_deal->match_time = $time;
            $main_deal->save();
            $sold_user_info = User::get($main_deal->user_id);
            send_matched_sms($sold_user_info->mobile,$main_deal->deal_sn);   //  发送短信提醒
            Db::commit();
            return true;
        }catch (\Exception $e) {
            Db::rollback();
            Log::error('匹配交易失败：'.json_encode($e->getMessage()));
            return $e->getMessage();
        }
    }



    //  正式匹配
    private function match_data($deal_list,$main_deal)
    {
        $time = time();
        \think\Config::load(APP_PATH.'api/config.php');

        //  生成要保存的数据
        $order_data = [];
        if ($main_deal->type == config('DealType.Buy'))
        {
            //  主为买入
            foreach ($deal_list as $item)
            {
                $order_data[] = [
                    'order_sn'  =>  generate_order_id($item->user_id),
                    'buy_deal_sn'   =>  $main_deal->deal_sn,
                    'buy_user_id'   =>  $main_deal->user_id,
                    'sale_deal_sn'  =>  $item->deal_sn,
                    'sale_user_id'  =>  $item->user_id,
                    'create_time'   =>  $time,
                    'pay_time'      =>  0,
                    'complete_time' =>  0,
                    'type'          =>  config('DealType.Buy'),
                    'status'        =>  config('OrderStatus.NoDeal'),
                    'cny'           =>  $item->cny
                ];
            }
        }
        else
        {
            //  主记录为卖出
            foreach ($deal_list as $item)
            {
                $order_data[] = [
                    'order_sn'      =>  generate_order_id($item->user_id),
                    'buy_deal_sn'   =>  $item->deal_sn,
                    'buy_user_id'   =>  $item->user_id,
                    'sale_deal_sn'  =>  $main_deal->deal_sn,
                    'sale_user_id'  =>  $main_deal->user_id,
                    'create_time'   =>  $time,
                    'pay_time'      =>  0,
                    'complete_time' =>  0,
                    'type'          =>  config('DealType.Sold'),
                    'status'        =>  config('OrderStatus.NoDeal'),
                    'cny'           =>  $item->cny
                ];
            }
        }

        //  事务保存
        $order = new Order();
        Db::startTrans();
        try{
            //  更新所有被勾选交易的状态
            foreach ($deal_list as $item)
            {
                $item->status = config('DealStatus.Dealing');
                $item->match_time = $time;
                $item->save();
            }
            //  批量生成 一对一 订单号
            $order->isUpdate(false)->allowField(true)->saveAll($order_data);
            //  更新主记录的状态
            $main_deal->status = config('DealStatus.Dealing');
            $main_deal->match_time = $time;
            $main_deal->save();
            Db::commit();
            return true;
        }catch (\Exception $e) {
            Db::rollback();
            Log::error('匹配交易失败：'.json_encode($e));
            return false;
        }
    }

    /**
     *  查询用户信息
     */
    public function search_user_info()
    {
        $ids = $this->request->request('ids');
        if (!$ids && $ids <= 0)
        {
            $user = new User();
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $user
                ->where($where)
                ->order($sort, $order)
                ->count();
            $list = $user
                ->where($where)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();
            $result = array("total" => $total, "rows" => $list);
            return json($result);
        }

        $user = new User();
        $where = [
            'id'    =>  ['like' , "$ids%"],
            'mobile'    =>  ['like' , "%$ids%"],
        ];
        $total = $user->whereOr($where)->count();
        $user_list = $user->whereOr($where)
            ->limit(0,20)
            ->select();
        return json(['total' => $total,'rows' => $user_list]);
    }

}
